package com.woniu.service.impl;



import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.woniu.entity.*;
import com.woniu.mapper.*;
import com.woniu.service.AlarmMessageService;
import com.woniu.service.AlarmSettingService;
import com.woniu.util.PageData;

import com.woniu.util.ResponseData;
import com.woniu.util.easyExcelUtil.EasyExcelUtil;
import com.woniu.vo.AlaramSettingVo;
import com.woniu.vo.AlarmMessageVo;
import com.woniu.vo.SettingExcelVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.*;

import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;



/**
* @author Apricity
* @description 针对表【alarm_setting(报警设置表)】的数据库操作Service实现
* @createDate 2025-02-13 20:16:58
*/
@Service
@Slf4j
public class AlarmSettingServiceImpl extends ServiceImpl<AlarmSettingMapper, AlarmSetting>
    implements AlarmSettingService{

    @Autowired
    private AlarmSettingMapper alarmSettingMapper;
    /*
    * 报警和电站关联
    * */
    @Autowired
    private AlarmStationRelationMapper alarmStationRelationMapper;
    /*
    * 报警和电桩关联
    * */
    @Autowired
    private AlarmChargerRelationMapper alarmChargerRelationMapper;
    /*
    * 充电站
    * */
    @Autowired
    private ChargingStationMapper chargingStationMapper;
    /*
    * 充电桩
    * */
    @Autowired
    private ChargerMapper chargerMapper;

    /*
    * 分页查询
    * */
    @Override
    public Page<AlaramSettingVo> pageQuery(PageData pageData) {
        int maxDisplay = 3;
        List<AlarmSetting> alarmSetting = alarmSettingMapper.selectList(null);
        List<AlaramSettingVo> voList = new ArrayList<>();
        for (AlarmSetting setting : alarmSetting) {
            AlaramSettingVo settingVo = new AlaramSettingVo();

            settingVo.setId(setting.getId());
            settingVo.setAlarmName(setting.getAlarmName());
            settingVo.setAlarmLevel(setting.getAlarmLevel());
            settingVo.setStatus(setting.getStatus());

            // 从 chargerId 查询 chargerName
            List<String> chargerNames = alarmChargerRelationMapper.findNamesByIds(setting.getId());
            List<String> displayChargerNames = new ArrayList<>();
            if (chargerNames != null && !chargerNames.isEmpty()) {
                if (chargerNames.size() > maxDisplay) {
                    // 取前 maxDisplay 个名称，然后追加 "..."
                    displayChargerNames.addAll(chargerNames.subList(0, maxDisplay));
                    displayChargerNames.add("...");
                } else {
                    displayChargerNames.addAll(chargerNames);
                }
            }
            settingVo.setChargerNames(displayChargerNames);

            // 从 stationId 查询 stationName
            List<String> stationNames = alarmStationRelationMapper.findNamesByIds(setting.getId());
            List<String> displayStationNames = new ArrayList<>();
            if (stationNames != null && !stationNames.isEmpty()) {
                if (stationNames.size() > maxDisplay) {
                    // 取前 maxDisplay 个名称，然后追加 "..."
                    displayStationNames.addAll(stationNames.subList(0, maxDisplay));
                    displayStationNames.add("...");
                } else {
                    displayStationNames.addAll(stationNames);
                }
            }
            settingVo.setStationNames(displayStationNames);

            voList.add(settingVo);

        }

        // 手动分页
        int pageNum = pageData.getPageNum();
        int pageSize = pageData.getPageSize();
        int total = voList.size();
        int fromIndex = (pageNum - 1) * pageSize;
        int toIndex = Math.min(fromIndex + pageSize, total);
        List<AlaramSettingVo> pageList = voList.subList(fromIndex, toIndex);

        Page<AlaramSettingVo> page = new Page<>(pageNum, pageSize);
        page.setTotal(total);
        page.setRecords(pageList);


        /*Page<AlaramSettingVo> page = new Page<>(pageData.getPageNum(), pageData.getPageSize());
        IPage<AlaramSettingVo> settingIPage = alarmSettingMapper.settingPageInfo(page, (String) pageData.getParam());
        return (Page<AlaramSettingVo>) settingIPage;*/
        return page;
    }

    /*
    * 新增
    * */
    @Override
    public void saveSetting(Map map) {
        AlarmSetting setting = new AlarmSetting();
        AlarmChargerRelation chargerRelation = new AlarmChargerRelation();
        AlarmStationRelation stationRelation = new AlarmStationRelation();

// 假设 map.get("form") 返回的是一个 Map，其 key 为字段名，value 为对应的值
        Map form = (Map) map.get("form");

// 遍历 Map 中的每个键值对
        form.forEach(new BiConsumer() {
            @Override
            public void accept(Object key, Object value) {
                // 遍历 AlarmSetting 类中所有声明的字段
                for (Field field : AlarmSetting.class.getDeclaredFields()) {
                    // 比较字段名称与 Map 的 key（需要转换成 String）
                    if (field.getName().equals(key.toString())) {
                        // 设置字段可以访问（如果是 private）
                        field.setAccessible(true);
                        try {
                            // 将 Map 中的值设置到对应的字段上
                            field.set(setting, value);
                        } catch (IllegalAccessException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        alarmSettingMapper.insert(setting);
        Long settingId = setting.getId();
        chargerRelation.setAlarmId(settingId);
        stationRelation.setAlarmId(settingId);

        /*alarmChargerRelationMapper.insert(chargerRelation);
        alarmStationRelationMapper.insert(stationRelation);*/

        ObjectMapper objectMapper = new ObjectMapper();
        List<Charger> chargerData = objectMapper.convertValue(
                map.get("chargerData"),
                new TypeReference<List<Charger>>() {}
        );
        for (Charger charger : chargerData) {
            Long chargerId = charger.getId();
            chargerRelation.setChargerId(chargerId);
            alarmChargerRelationMapper.insert(chargerRelation);
        }


        List<ChargingStation> stationData = objectMapper.convertValue(
                map.get("stationData"),
                new TypeReference<List<ChargingStation>>() {}
        );
        for (ChargingStation station : stationData) {
            Long stationId = station.getId();
            stationRelation.setStationId(stationId);
            alarmStationRelationMapper.insert(stationRelation);
        }
    }

    @Override
    public AlarmSetting getId(Long id) {
        // 查询报警设置表
        AlarmSetting setting = alarmSettingMapper.selectById(id);
        log.info("settngone: {}", setting);
        Long settingId = setting.getId();
        log.info("settngoneId: {}", settingId);
        //查询联动表
        // 充电桩
        List<AlarmChargerRelation> alarmChargerRelations =
                alarmChargerRelationMapper.selectList(new QueryWrapper<AlarmChargerRelation>().eq("alarm_id", settingId));
        List<Long> chargerIds = alarmChargerRelations.stream()
                .map(AlarmChargerRelation::getChargerId)
                .collect(Collectors.toList());
        List<Charger> chargers = chargerIds.isEmpty() ? Collections.emptyList() :
                chargerMapper.selectList(new QueryWrapper<Charger>().in("id", chargerIds));

        // 充电站
        List<AlarmStationRelation> stationRelations =
                alarmStationRelationMapper.selectList(new QueryWrapper<AlarmStationRelation>().eq("alarm_id", settingId));
        List<Long> stationIds = stationRelations.stream()
                .map(AlarmStationRelation::getStationId).collect(Collectors.toList());
        List<ChargingStation> stations = stationIds.isEmpty() ? Collections.emptyList() :
                chargingStationMapper.selectList(new QueryWrapper<ChargingStation>().in("id", stationIds));


        AlarmSetting alarmSetting = new AlarmSetting();
        alarmSetting.setId(setting.getId());
        alarmSetting.setAlarmName(setting.getAlarmName());
        alarmSetting.setAlarmLevel(setting.getAlarmLevel());
        alarmSetting.setStatus(setting.getStatus());
        alarmSetting.setCreatedAt(setting.getCreatedAt());
        alarmSetting.setDescription(setting.getDescription());
        alarmSetting.setChargerIds(chargers);
        alarmSetting.setStationIds(stations);

        return alarmSetting;
    }

    @Override
    public void updateStatus(Integer status, Long id) {
        //修改状态
        AlarmSetting setting = new AlarmSetting();
        setting.setStatus(status);
        setting.setId(id);

        alarmSettingMapper.updateById(setting);
    }

    @Override
    @Transactional
    public void deleteSetting(List<Long> alarmIds) {
        // 删除报警和电站关联
        alarmStationRelationMapper.deleteASR(alarmIds);
        // 删除报警和电桩关联
        alarmChargerRelationMapper.deleteACR(alarmIds);
        alarmSettingMapper.deleteSettings(alarmIds);

    }

    @Override
    @Transactional
    public void updateSetting(Map<String, Object> param) {
        AlarmSetting setting = new AlarmSetting();
        AlarmChargerRelation chargerRelation = new AlarmChargerRelation();
        AlarmStationRelation stationRelation = new AlarmStationRelation();

        Map form = (Map) param.get("form");
        form.forEach((key, value) -> {
            for (Field field : AlarmSetting.class.getDeclaredFields()) {
                if (field.getName().equals(key.toString())){
                    field.setAccessible(true);

                    try {
                        if("id".equals(key.toString())){
                            Long id = value instanceof Long ? (Long) value : Long.valueOf(value.toString());
                            field.set(setting, id);
                        }else {
                            field.set(setting, value);
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        alarmSettingMapper.updateById(setting);

        //删除两张关联表
        alarmChargerRelationMapper.delete(new QueryWrapper<AlarmChargerRelation>().eq("alarm_id", setting.getId()));
        alarmStationRelationMapper.delete(new QueryWrapper<AlarmStationRelation>().eq("alarm_id", setting.getId()));

        chargerRelation.setAlarmId(setting.getId());
        stationRelation.setAlarmId(setting.getId());

        ObjectMapper mapper = new ObjectMapper();
        List<Charger> chargers = mapper.convertValue(param.get("chargerData"), new TypeReference<List<Charger>>() {});
        for (Charger charger : chargers) {
            Long chargerId = charger.getId();
            chargerRelation.setChargerId(chargerId);
            alarmChargerRelationMapper.insert(chargerRelation);
        }

        List<ChargingStation> stationList = mapper.convertValue(param.get("stationData"), new TypeReference<List<ChargingStation>>() {});
        for (ChargingStation station : stationList) {
            Long stationId = station.getId();
            stationRelation.setStationId(stationId);
            alarmStationRelationMapper.insert(stationRelation);
        }
    }

    @Override
    public ResponseData<?> outDepartmentExcelTemplate(HttpServletResponse response) throws IOException {
        String fileName = "报警设置模板";

        // 获取数据库数据
        List<SettingExcelVo> dataList = getMaintenancePersons();

        // **设置 Excel 响应头**
        response.setContentType("application/vnd.ms-excel");
        response.setCharacterEncoding("utf-8");
        response.setHeader("Content-Disposition", "attachment;filename="
                + URLEncoder.encode(fileName, "UTF-8") + ".xlsx");


            EasyExcelUtil.writeWithSheetsWeb(response, fileName)
                    .writeModel(SettingExcelVo.class, dataList, "settingName1")
                    .finish();

        return ResponseData.ok();
    }

    private List<SettingExcelVo> getMaintenancePersons() {
        ArrayList<SettingExcelVo> list = new ArrayList<>();
        List<AlaramSettingVo> settingList = alarmSettingMapper.selectSetting();

        StringJoiner station = new StringJoiner(",");
        StringJoiner charger = new StringJoiner(",");
        for (AlaramSettingVo settingVo : settingList) {
            SettingExcelVo vo = new SettingExcelVo();
            //充电站 xxx,xxx,xxx
            List<String> stationList = alarmStationRelationMapper.findNamesByIds(settingVo.getId());
            for (String s : stationList) {
                station.add(s);
            }
            vo.setStationNames(station.toString());

            //充电桩 xxx,xxx,xxx
            List<String> chargerList = alarmChargerRelationMapper.findNamesByIds(settingVo.getId());
            for (String s : chargerList) {
                charger.add(s);
            }
            vo.setChargerNames(charger.toString());

            BeanUtils.copyProperties(settingVo, vo);

            list.add(vo);
        }

        return list;
    }
}




